home *** CD-ROM | disk | FTP | other *** search
- ; AMSAT/TAPR DSP BEL-202 modem. Filter splitter design
- ; Sample rate should be set to 9600 samples/sec.
- ; code by Bob McGwier N4HY
- org 0
- b go
- org 16
- sine: equ 0 ; will store sine values from tone
- one: equ 1 ; guess what goes here duhhhhh!
- energy: equ 2
- thresh: equ 3
- maskl: equ 4 ; mask for fine or low order bits of phase
- mask: equ 5 ; mask for doing modulo 16384 arithmetic with phase
- sinx: equ 6 ; used to store coarse sine value (high order bits)
- cosx: equ 7 ; as above for cosine
- mone: equ 8 ; minus one stored here
- wkph: equ 9 ; different phases (PLL, remodulator tone etc) are stored hr
- ; for frequency synthesis
- masko: equ 10 ; mask for converting on board PCM to DAC format
- mps: equ 11 ; multiplier for quadrant determination for sine
- mpc: equ 12 ; multiplier for quadrant determination for cosine
- siny: equ 13 ; fine correction value for use in SIN(X+Y) = sinx*cosy+
- cosy: equ 14 ; cosx*siny
- cosine: equ 15 ; cosine is also needed for Q arm in Costas loop
- coph: equ 16 ; working number holder
- modem: equ 17 ; Used to choose between complex tone for arms and real tone
- ; in the modulator as explained below
- xn0: equ 18
- xn1: equ 19
- xn2: equ 20
- xn3: equ 21
- xn4: equ 22
- xn5: equ 23
- xn6: equ 24
- xn7: equ 25
- xn8: equ 26
- xn9: equ 27
- xn10: equ 28
- xn11: equ 29
- xn12: equ 30
- xn13: equ 31
- xn14: equ 32
- xn15: equ 33
- xn16: equ 34
- xn17: equ 35
- xn18: equ 36
- xn19: equ 37
- xn20: equ 38
- xn21: equ 39
- xn22: equ 40
- xn23: equ 41
- xn24: equ 42
- xn25: equ 43
- xn26: equ 44
- xn27: equ 45
- xn28: equ 46
- xn29: equ 47
- xn30: equ 48
- xn31: equ 49
- xn32: equ 50
- b0: equ 51
- b1: equ 52
- b2: equ 53
- b3: equ 54
- b4: equ 55
- b5: equ 56
- b6: equ 57
- b7: equ 58
- b8: equ 59
- b9: equ 60
- b10: equ 61
- b11: equ 62
- b12: equ 63
- b13: equ 64
- b14: equ 65
- b15: equ 66
- b16: equ 67
- b17: equ 68
- b18: equ 69
- b19: equ 70
- b20: equ 71
- freql: equ 72 ; low tone for remodulator stored here
- freqh: equ 73 ; high tone remod.
- freqo: equ 74 ; freqo is assigned one of the values above for remod
- phaseo: equ 75 ; phaseo is the phase of the remodulator output. phase is
- hl12: equ 76
- hl13: equ 77
- hl15: equ 78
- hl16: equ 79
- hu13: equ 80
- hu14: equ 81
- hu16: equ 82
- hb8: equ 83
- hb9: equ 84
- hb10: equ 85
- tester: equ 86
- suml: equ 87
- sumh: equ 88
- clockp: equ 89
- clockf: equ 90
- clocke: equ 91
- clocka: equ 92
- sintbl:
- dw 0 ; coarse sine table in steps of PI/64 radians to PI/2
- dw 804
- dw 1607
- dw 2410
- dw 3211
- dw 4011
- dw 4807
- dw 5601
- dw 6392
- dw 7179
- dw 7961
- dw 8739
- dw 9511
- dw 10278
- dw 11038
- dw 11792
- dw 12539
- dw 13278
- dw 14009
- dw 14732
- dw 15446
- dw 16150
- dw 16845
- dw 17530
- dw 18204
- dw 18867
- dw 19519
- dw 20159
- dw 20787
- dw 21402
- dw 22004
- dw 22594
- dw 23169
- dw 23731
- dw 24278
- dw 24811
- dw 25329
- dw 25831
- dw 26318
- dw 26789
- dw 27244
- dw 27683
- dw 28105
- dw 28510
- dw 28897
- dw 29268
- dw 29621
- dw 29955
- dw 30272
- dw 30571
- dw 30851
- dw 31113
- dw 31356
- dw 31580
- dw 31785
- dw 31970
- dw 32137
- dw 32284
- dw 32412
- dw 32520
- dw 32609
- dw 32678
- dw 32727
- dw 32757
- dw 32767 ; PI/2
- fines: dw 0 ; fine sine table in steps of PI/(64*64) radians to PI/64
- dw 12
- dw 25
- dw 37
- dw 50
- dw 62
- dw 75
- dw 87
- dw 100
- dw 113
- dw 125
- dw 138
- dw 150
- dw 163
- dw 175
- dw 188
- dw 201
- dw 213
- dw 226
- dw 238
- dw 251
- dw 263
- dw 276
- dw 289
- dw 301
- dw 314
- dw 326
- dw 339
- dw 351
- dw 364
- dw 376
- dw 389
- dw 402
- dw 414
- dw 427
- dw 439
- dw 452
- dw 464
- dw 477
- dw 490
- dw 502
- dw 515
- dw 527
- dw 540
- dw 552
- dw 565
- dw 578
- dw 590
- dw 603
- dw 615
- dw 628
- dw 640
- dw 653
- dw 665
- dw 678
- dw 691
- dw 703
- dw 716
- dw 728
- dw 741
- dw 753
- dw 766
- dw 779
- dw 791
- finec: dw 32767 ;ditto to above for fine sine
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32765
- dw 32765
- dw 32765
- dw 32765
- dw 32765
- dw 32765
- dw 32765
- dw 32765
- dw 32764
- dw 32764
- dw 32764
- dw 32764
- dw 32764
- dw 32764
- dw 32764
- dw 32763
- dw 32763
- dw 32763
- dw 32763
- dw 32763
- dw 32762
- dw 32762
- dw 32762
- dw 32762
- dw 32762
- dw 32761
- dw 32761
- dw 32761
- dw 32761
- dw 32760
- dw 32760
- dw 32760
- dw 32760
- dw 32759
- dw 32759
- dw 32759
- dw 32759
- dw 32758
- dw 32758
- dw 32758
- dw 32758
- dw 32757
- dw 32757
- filtd:
- dw -4178
- dw -5415
- dw 4323
- dw 7299
-
- dw -4545
- dw -5167
- dw 6951
-
- dw 4513
- dw 8819
- dw 10635
- go: ldpk 0 ; make sure that we are pointing to 0 data page
- lack one ; make and store one
- sacl one
- lac one,11
- sacl clockf
- lack filtd ; store address of the too large coefficients
- tblr hl12
- add one
- tblr hl13
- add one
- tblr hl15
- add one
- tblr hl16
- add one
- tblr hu13
- add one
- tblr hu14
- add one
- tblr hu16
- add one
- tblr hb8
- add one
- tblr hb9
- add one
- tblr hb10
- sacl masko
- lt one
- mpyk 3755
- pac
- sacl freqh
- lac one,4
- sacl thresh
- lt one
- mpyk 2048
- pac
- sacl freql
- zac
- sacl clockp
- sub one
- sacl mone ; make and store minus one
- sacl modem
- lac one,14
- sub one
- sacl mask ; make and store mask for modulo 16384 phase arithmetic
- lac one,6
- sub one
- sacl maskl ; make and store fine part of address mask;
- lac one,8 ; make and store frequency address in memory
- sub one
-
- ; Okay the BS is over lets get to work !
-
- wait: bioz fire ; is it time for a new sample
- b wait ; nope go wait in the corner
- fire: in xn0,pa3 ; get a new sample here
-
- lac xn0,4
- sub one,15 ; Change ADC format to two's complement
- sacl xn0
-
- ; remodulator output
-
- lac thresh
- sub energy
- bgz noout
- lac sine,6
- addh masko
- sach b0
- out b0,pa4 ; send it to the TNC here
- ; as the following routines have a variable length
- ; end output
- noout: lack one ;
- sacl mps ; Restore sine and cosine quadrant multipliers
- sacl mpc ;
- ;
- ; FINITE IMPULSE RESPONSE (FIR)
- ; LINEAR PHASE DIGITAL FILTER DESIGN
- ; REMEZ EXCHANGE ALGORITHM
-
- ; BANDPASS FILTER
-
- ; FILTER LENGTH = 33
- ;
- ; BAND 1 BAND 2 BAND 3
- ; LOWER BAND EDGE .0000000 .1150000 .2290000
- ; UPPER BAND EDGE .0550000 .1770000 .5000000
- ; DESIRED VALUE .0000000 1.0000000 .0000000
- ; WEIGHTING 1.0000000 1.0000000 1.0000000
- ; DEVIATION .0158519 .0158519 .0158519
- ; DEVIATION IN DB -35.9983500 .1366083 -35.9983500
-
- ; EXTREMAL FREQUENCIES--MAXIMA OF THE ERROR CURVE
- ; .0000000 .0404412 .0550000 .1150000 .1241912
- ; .1462500 .1664706 .1770000 .2290000 .2381912
- ; .2620883 .2896618 .3190736 .3503236 .3834119
- ; .4146619 .4514267 .5000000
- ;
- ; FILTER for low side with the filter given above
- ;
- zac ; Zero the accumulator as we will be summing as we multiply
- lt xn32
- mpyk 270
-
- lta xn31
- mpyk -212
-
- lta xn30
- mpyk -670
-
- lta xn29
- mpyk -680
-
- lta xn28
- mpyk -25
-
- lta xn27
- mpyk 610
-
- lta xn26
- mpyk 479
-
- lta xn25
- mpyk -19
-
- lta xn24
- mpyk 317
-
- lta xn23
- mpyk 1577
-
- lta xn22
- mpyk 1907
-
- lta xn21
- mpyk -447
-
- lta xn20
- mpy hl12
-
- lta xn19
- mpy hl13
-
- lta xn18
- mpyk -1748
-
- lta xn17
- mpy hl15
-
- lta xn16
- mpy hl16
-
- lta xn15
- mpy hl15
-
- lta xn14
- mpyk -1748
-
- lta xn13
- mpy hl13
-
- lta xn12
- mpy hl12
-
- lta xn11
- mpyk -447
-
- lta xn10
- mpyk 1907
-
- lta xn9
- mpyk 1507
-
- lta xn8
- mpyk 317
-
- lta xn7
- mpyk -19
-
- lta xn6
- mpyk 479
-
- lta xn5
- mpyk 610
-
- lta xn4
- mpyk -25
-
- lta xn3
- mpyk -680
-
- lta xn2
- mpyk -670
-
- lta xn1
- mpyk -212
-
- lta xn0
- mpyk 270
- apac
- sach suml ; suml is the low side filter output
- bgez posl
- zac
- sub suml
- sacl suml
- posl:
- ;
- ;
- ; FINITE IMPULSE RESPONSE (FIR)
- ; LINEAR PHASE DIGITAL FILTER DESIGN
- ; REMEZ EXCHANGE ALGORITHM
-
- ; BANDPASS FILTER
-
- ; FILTER LENGTH = 33
-
- ; BAND 1 BAND 2 BAND 3
- ; LOWER BAND EDGE .0000000 .1770000 .2900000
- ; UPPER BAND EDGE .1200000 .2290000 .5000000
- ; DESIRED VALUE .0000000 1.0000000 .0000000
- ; WEIGHTING 1.0000000 1.0000000 1.0000000
- ; DEVIATION .0114788 .0114788 .0114788
- ; DEVIATION IN DB -38.8020300 .0991361 -38.8020300
- ;
- ; FILTER for high side with the filter given above
- ;
-
- zac ; Zero the accumulator as we will be summing as we multiply
- lt xn32
- mpyk -43
-
- ltd xn31
- mpyk -642
-
- ltd xn30
- mpyk -196
-
- ltd xn29
- mpyk 612
-
- ltd xn28
- mpyk 600
-
- ltd xn27
- mpyk -201
-
- ltd xn26
- mpyk -275
-
- ltd xn25
- mpyk 115
-
- ltd xn24
- mpyk -726
-
- ltd xn23
- mpyk -1492
-
- ltd xn22
- mpyk 785
-
- ltd xn21
- mpyk 3790
-
- ltd xn20
- mpyk 1545
-
- ltd xn19
- mpy hu13
-
- ltd xn18
- mpy hu14
-
- ltd xn17
- mpyk 2078
-
- ltd xn16
- mpy hu16
-
- ltd xn15
- mpyk 2078
-
- ltd xn14
- mpy hu14
-
- ltd xn13
- mpy hu13
-
- ltd xn12
- mpyk 1545
-
- ltd xn11
- mpyk 3790
-
- ltd xn10
- mpyk 785
-
- ltd xn9
- mpyk -1492
-
- ltd xn8
- mpyk -726
-
- ltd xn7
- mpyk 115
-
- ltd xn6
- mpyk -275
-
- ltd xn5
- mpyk -201
-
- ltd xn4
- mpyk 600
-
- ltd xn3
- mpyk 612
-
- ltd xn2
- mpyk -196
-
- ltd xn1
- mpyk -642
-
- ltd xn0
- mpyk -43
- apac
- sach sumh ; sumh is the high side filter output
- bgez posh
- zac
- sub sumh
- sacl sumh
- posh:
- ; load the high filter value subtract the low filter value
- ; send this through the LPF.
- lac sumh
- sub suml
- sacl b0
- ; See if there is energy in the filters and use this as a data
- ; squelch. In other words, you must use the squelch on your radio
- ; to turn the data squelch on and off
- lac sumh,15
- add suml,15
- add energy,15
- sach energy
-
-
- ; FINITE IMPULSE RESPONSE (FIR)
- ; LINEAR PHASE DIGITAL FILTER DESIGN
- ; REMEZ EXCHANGE ALGORITHM
-
- ; BANDPASS FILTER
-
- ; FILTER LENGTH = 21
-
- ; BAND 1 BAND 2
- ; LOWER BAND EDGE .0000000 .1750000
- ; UPPER BAND EDGE .1250000 .5000000
- ; DESIRED VALUE 1.0000000 .0000000
- ; WEIGHTING 1.0000000 1.0000000
- ; DEVIATION .0687429 .0687429
- ; DEVIATION IN DB .5774649 -23.2554400
- ;
- ; LPF the splitter output and this is the bits
- ;
- ;
- ; If the bit is positive output 2200 else output 1200
- ;
- zac
-
- lt b20
- mpyk -431
-
- ltd b19
- mpyk 323
-
- ltd b18
- mpyk 821
-
- ltd b17
- mpyk 801
-
- ltd b16
- mpyk -185
-
- ltd b15
- mpyk -1568
-
- ltd b14
- mpyk -1844
-
- ltd b13
- mpyk 269
-
- ltd b12
- mpy hb8
-
- ltd b11
- mpy hb9
-
- ltd b10
- mpy hb10
-
- ltd b9
- mpy hb9
-
- ltd b8
- mpy hb8
-
- ltd b7
- mpyk 269
-
- ltd b6
- mpyk -1844
-
- ltd b5
- mpyk -1568
-
- ltd b4
- mpyk -185
-
- ltd b3
- mpyk 801
-
- ltd b2
- mpyk 821
-
- ltd b1
- mpyk 323
-
- ltd b0
- mpyk -431
- apac
- sach b0
- ; b0 contains the bandlimited noisy bit value. Recover the clock
- ; so that we may choose point of maximum eye opening for the bit
- ; decision.
- ;
- ; The clock recovery nonlinearity begins with absolute value
- lac b0
- bgez addc
- zac
- sub b0
- addc: sacl clocke
- ; Keep a IIR LPF version of this so that the DC may be subtracted
- ; and get a clock tone at the data rate.
- ; Simplest IIR, 0.5*old value + 0.5 * new value
- ;
- lac clocka,15
- add clocke,15
- sach clocka
- ; Subtract off DC
- lac clocke
- sub clocka
- sacl clocke
- ; get sine from tones that runs at the clock rate
- lac clockp
- call tones
- zac
- ; mix (multiply) with the clock signal from above
- lt sine
- mpy clocke
- spac
- ; taking the negative of this (spac from a zero'd accumulator)
- sach clocke
- ; using a gain of 1/8 add correction into the old clock phase plus
- ; the phase increment (frequency)
- lac clocke,13
- sach clocke
- lac clockf
- add clockp
- add clocke
- sacl clockp
- ; After storing the new clock phase test to see if we have passed
- ; two pi at which time we will take the value of b0 for the bit value
- ; Since this is the point of maximal eye opening. If the phase has
- ; been corrected negative put back between 0 and 2pi.
- bgez gpi
- add one,14
- sacl clockp
- b outt
- gpi: lac one,14
- sub clockp
- blz nfrq
- b outt
- nfrq: lac clockp
- and mask
- sacl clockp
- lac b0
- ; bit positive?
- bgez posb
- ; No load low frequency for this bit period
- lac freql
- b newf
- ; Yes load high frequency for this bit period
- posb: lac freqh
- newf: sacl freqo
- ; freqo is the output frequency for the remodulator
- outt: lack one
- sacl mpc
- sacl mps
- lac freqo
- add phaseo
- and mask
- sacl phaseo
- call tones
- b wait
- ; complex tone generator if modem>0 if modem<0 sine wave generator
-
- tones: sacl wkph ; store a working copy
- lac wkph,4
- subh one
- blz getem ; is it in a quadrant bigger than first?
- subh one
- bgez thfr; is it in a quadrant greater than two?
- lac 1,13 ; nope so load pi
- sub wkph ; subtract phase so that it maps back into 1st quad
- sacl wkph ; store
- lac mone ; load -1
- sacl mpc ; store it in the cosine multiplier
- b getem ; go read tables
- thfr: lac mone ; multiplier for bottom half
- sacl mps ; store
- lac wkph ;
- sub one,13 ; map angle back to upper half and go do it again
- b tones
- getem: lac wkph,10 ; take 1st quadrant phase equiv for sine and pick
- ; off coarse part of phase address
- sach coph ; store it
- lack sintbl ; load sine table offset into accumulator
- add coph ; add coarse address off set
- tblr sinx ; read the coarse sine value
- lac one,6 ; load pi/2
- sub coph ; subtract the coarse phase to get cosines offset
- sacl coph
- lack sintbl
- add coph ; do same as above for coarse cosine
- tblr cosx
- lac wkph ; load working phase
- and maskl ; mask off fine addres
- sacl coph ; store it
- lack fines ; locate fine table offset
- add coph ; add for offset into fine table
- tblr siny ; read table
- lack finec
- add coph
- tblr cosy
- zac
- lt sinx ; load sinx
- mpy cosy ; multiply by cosy
- lta siny ; load t reg with fine sin and accumulate previous prod.
- mpy cosx ; multiply by coarse cosx to use sin(X+Y)
- apac ; add the result to coarse sine
- sach sine ; store it.
- lac modem
- blz mult
- lac 1,12 ; load full address pi/2
- sub wkph ; subtract the working phase to get cosine
- sacl wkph
- lac wkph,10 ; from here to the later MARK it is identical to above
- sach coph
- lack sintbl
- add coph
- tblr sinx
- lac one,6
- sub coph
- sacl coph
- lack sintbl
- add coph
- tblr cosx
- lac wkph
- and maskl
- sacl coph
- lack fines
- add coph
- tblr siny
- lack finec
- add coph
- tblr cosy
- zac
- lt cosy
- mpy sinx
- lta siny
- mpy cosx
- apac ; MARK
- sach cosine ; store it in the cosine
- mult: lt mps; now we need to do a few multiplies by sign changes due to
- mpy sine ; to quadrant part of phase address
- pac; multiply sine by sine sign (:-) and
- sacl sine ; store the result
- lac modem
- bgz cosm
- ret
- cosm: mpy cosine; now multiply cosine by the same
- pac
- sacl cosine ; store it
- lt mpc; load cosine differentiator from sine sign (:-)
- mpy cosine; multiply
- pac
- sacl cosine ; store
- ret
- end
- ; Ebbly Ebbly Ebbly thats all folks
-
-
-
-